﻿#region Copyright (c) 2010 Rinat Abdullin and LOKAD SAS.

// Copyright (c) 2010 Rinat Abdullin and LOKAD SAS. 
// This software is released for  free use under the terms 
// of the GNU General Public License, version 2 or higher.

#endregion

// we need to use GNU GPL here to include rinetd.exe in the source.
// Actual sources could be used under New BSD License (allows commercial reuse). 
// Project itself could to help with routing anywere.
// Home page: http://code.google.com/p/lokad-azure-tcp-tunnel

using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace TcpRouter
{
	public class WorkerRole : RoleEntryPoint
	{
		public override void Run()
		{
			var point = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Incoming"].IPEndpoint;
			var host = RoleEnvironment.GetConfigurationSettingValue("Host");
			var port = RoleEnvironment.GetConfigurationSettingValue("Port");

			var tempFileName = Path.GetTempFileName();

			File.WriteAllText(tempFileName, string.Format("0.0.0.0 {0} {1} {2}", point.Port, host, port));
			var process = new Process
				{
					StartInfo =
						{
							UseShellExecute = false,
							RedirectStandardOutput = true,
							RedirectStandardError = true,
							CreateNoWindow = true,
							ErrorDialog = false,
							FileName = "rinetd.exe",
							WindowStyle = ProcessWindowStyle.Hidden,
							Arguments = "-c \"" + tempFileName + "\"",
						},
					EnableRaisingEvents = false
				};

			process.Start();

			process.BeginOutputReadLine();
			process.BeginErrorReadLine();

			process.WaitForExit();
		}

		public override bool OnStart()
		{
			// Set the maximum number of concurrent connections 
			ServicePointManager.DefaultConnectionLimit = 12;
			RoleEnvironment.Changing += RoleEnvironmentChanging;

			return base.OnStart();
		}

		static void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
		{
			// If a configuration setting is changing
			if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
			{
				// Set e.Cancel to true to restart this role instance
				e.Cancel = true;
			}
		}
	}
}